/*
 * Copyright (C) 2006-2011 Crise, crise<at>mail.berlios.de
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef PLUGIN_CONFIG_DLG
#define PLUGIN_CONFIG_DLG

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <atlctrlx.h>

#include "ExListViewCtrl.h"
#include "resource.h"

#include "../client/PluginManager.h"

class PluginConfigDlg : public CDialogImpl<PluginConfigDlg>
{
public:
	enum { IDD = IDD_PLUGIN_CONFIG };

	PluginConfigDlg(const string& pluginGuid) : guid(pluginGuid) { }
	~PluginConfigDlg() { }

	BEGIN_MSG_MAP(PluginConfigDlg)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		COMMAND_ID_HANDLER(IDOK, OnCloseCmd)
		COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
		COMMAND_ID_HANDLER(IDC_SETTING_SET, OnSetValue)
		NOTIFY_HANDLER(IDC_SETTINGS, LVN_ITEMCHANGED, OnItemChanged)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
		// Translate dialog
		SetWindowText(CTSTRING(PLUGIN_ADVANCED_CONFIG));
		SetDlgItemText(IDOK, CTSTRING(OK));
		SetDlgItemText(IDCANCEL, CTSTRING(CANCEL));

		SetDlgItemText(IDC_SETTING_SET, CTSTRING(SET));
		SetDlgItemText(IDC_PLUGIN_CONFIG_NOTE, CTSTRING(NOTICE));
		SetDlgItemText(IDC_PLUGIN_CONFIG_NOTE_TEXT, CTSTRING(PLUGIN_CONFIG_NOTE));

		settings.Attach(GetDlgItem(IDC_SETTINGS));
		value.Attach(GetDlgItem(IDC_SETTING_VALUE));

		CRect rc;
		settings.GetClientRect(rc);
		settings.InsertColumn(0, CTSTRING(SETTINGS_NAME), LVCFMT_LEFT, rc.Width() / 5, 0);
		settings.InsertColumn(1, CTSTRING(VALUE), LVCFMT_LEFT, ((rc.Width() / 5) * 4) - GetSystemMetrics(SM_CXVSCROLL), 1);
		settings.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);

		PluginManager::getInstance()->processSettings(guid, [this](StringMap& config) { fillList(config); });

		settings.setSort(0, ExListViewCtrl::SORT_STRING);
		return TRUE;
	}

	LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
		if(wID == IDOK)
			PluginManager::getInstance()->processSettings(guid, [this](StringMap& config) { updateConfig(config); });

		settings.Detach();
		value.Detach();

		EndDialog(wID);
		return 0;
	}

	LRESULT OnSetValue(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
		int sel = -1;
		if((sel = settings.GetNextItem(sel, LVNI_SELECTED)) != -1) {
			tstring buf;
			size_t len = value.GetWindowTextLength() + 1;

			buf.resize(len);
			buf.resize(value.GetWindowText(&buf[0], len));

			settings.SetItemText(sel, 1, buf.c_str());
		}

		return 0;
	}

	LRESULT OnItemChanged(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) {
		NM_LISTVIEW* lv = (NM_LISTVIEW*) pnmh;
		BOOL bEnable = settings.GetItemState(lv->iItem, LVIS_SELECTED);

		::EnableWindow(GetDlgItem(IDC_SETTING_VALUE), bEnable);
		::EnableWindow(GetDlgItem(IDC_SETTING_SET), bEnable);

		if(bEnable) {
			value.SetWindowText(getColumnText(lv->iItem, 1).c_str());
		} else value.SetWindowText(Util::emptyStringT.c_str());

		return 0;
	}

private:
	PluginConfigDlg(const PluginConfigDlg&) { dcassert(0); }

	void fillList(const StringMap& cfg) {
		auto idx = settings.GetItemCount();
		TStringList cols;
		for(auto i = cfg.cbegin(); i != cfg.cend(); ++i) {
			cols.clear();
			cols.push_back(Text::toT(i->first));
			cols.push_back(Text::toT(i->second));
			settings.insert(idx++, cols);
		}
	}

	void updateConfig(StringMap& cfg) {
		cfg.clear();
		auto count = settings.GetItemCount();
		for(auto i = 0; i < count; ++i)
			cfg[Text::fromT(getColumnText(i, 0))] = Text::fromT(getColumnText(i, 1));
	}

	tstring getColumnText(size_t idx, size_t col) {
		tstring valBuf;
		valBuf.resize(128);
		int ret = 0;
		do {
			valBuf.resize(valBuf.size() * 2);
			ret = settings.GetItemText(idx, col, &valBuf[0], valBuf.size());
		} while(ret > valBuf.size());
		valBuf.resize(ret);
		return valBuf;
	}

	ExListViewCtrl settings;
	CEdit value;

	string guid;
};

#endif